package com.voxel.sense.infomsg.widget.map.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.Text;
import com.example.com.common.utils.SizeUtils;
import com.voxel.sense.infomsg.interfaces.listener.onAddMarkerListener;
import com.voxel.sense.infomsg.utils.marker.cluster.data.ClusterItem;
import com.voxel.sense.infomsg.utils.cover.EntityConvertStrategy;
import com.voxel.sense.infomsg.utils.marker.cluster.strategy.StaffConverStrategey;
import com.voxel.sense.infomsg.widget.map.cluster.Cluster;
import com.voxel.sense.infomsg.widget.map.cluster.ClusterClickListener;
import com.voxel.sense.infomsg.widget.map.cluster.ClusterOverlay;
import com.voxel.sense.infomsg.widget.map.cluster.ClusterRender;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import cyy.example.com.facotry.Factory;
import cyy.example.com.facotry.constants.Constants;
import cyy.example.com.facotry.constants.EventBusConstants;
import cyy.example.com.facotry.model.EventEntity;
import cyy.example.com.facotry.model.api.response.MissionLocationEntity;
import cyy.example.com.facotry.model.api.response.StaffLocationInfoEntity;

/**
 * Created by ChenYiYao on 2018/6/4.
 * 地图marker的管理类
 */
public class MarkerManageUtils implements ClusterRender, IMarkerManage, onAddMarkerListener, AMap.OnCameraChangeListener {


    private Map<String, Drawable> mDrawables;//自定义图标的图标
    private Map<String, ClusterOverlay> mOverlayMap;//聚合操作类的集合
    private Map<String, List> mDatas;//数据源
    private AMap mAMap;
    private int clusterRadius = 50;
    private Drawable mClusterDra;
    private Drawable mClusterDra1;
    private HandlerThread mHandlerThread = new HandlerThread("operateDate");
    private Handler mHandler;
    private final static String S_STYPE = "S_STYPE";
    private OnCtmMarkerClickListener mMarkerClickListener;
    private onAddMarkerListener mAddMarkerListener;

    public MarkerManageUtils(AMap aMap) {
        this(aMap, null);
    }

    public MarkerManageUtils(AMap aMap, OnCtmMarkerClickListener listener) {
        mDrawables = new HashMap<>();
        mOverlayMap = new HashMap<>();
        mDatas = new HashMap<>();
        mAMap = aMap;
        int radius = SizeUtils.dp2px(50);
        mClusterDra = new BitmapDrawable(null, drawCircle(radius,
                Color.argb(159, 210, 154, 6)));
        mClusterDra1 = new BitmapDrawable(null, drawCircle(radius,
                Color.argb(200, 215, 66, 2)));
        initThreadHandler();
        mMarkerClickListener = listener;
        mAMap.setOnCameraChangeListener(this);
    }


    public void initMapData() {
    }

    @Override
    public void addMarkers(List list, String type, Drawable drawable, EntityConvertStrategy strategy) {
        mDrawables.put(type, drawable);
        addMarkers(list, type, strategy);
    }

    @Override
    public void addMarkers(final List list, final String type, final EntityConvertStrategy strategy) {
        List<ClusterItem> list1 = strategy.convertEntity(list, type);
        initData(list1, type);
    }

    @Override
    public void addMarker(Object data, String type, EntityConvertStrategy strategy) {
    }

    @Override
    public void addMarker(Object data, String type, Drawable drawable, EntityConvertStrategy strategy) {
    }

    @Override
    public void refreshMarkers(List list, String type, EntityConvertStrategy strategy) {
        List<ClusterItem> datas = strategy.convertEntity(list, type);
        boolean b = mDatas.containsKey(type);
        //清除数据
        if (b) {
            List list1 = mDatas.get(type);
            list1.clear();
            list1.add(list);
        } else {
            List data = new ArrayList();
            mDatas.put(type, list);
        }
        //数据构造完成，发送通知，构建聚合marker
        Message message = new Message();
        message.obj = datas;
        message.what = DataHandle.REFRESH_DATA;
        Bundle bundle = new Bundle();
        bundle.putString(S_STYPE, type);
        message.setData(bundle);
        mHandler.sendMessage(message);

    }

    @Override
    public boolean cleanMarkers() {
        return false;
    }

    @Override
    public void setSomeTypeMarkersVisible(final String type, final boolean visible, boolean foreceRefData) {
        final ClusterOverlay clusterOverlay = mOverlayMap.get(type);
        if (clusterOverlay == null)
            return;

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (clusterOverlay != null) {
                    List<ClusterItem> clusterItems = clusterOverlay.getClusterItems();
                    for (ClusterItem item : clusterItems) {
                        item.setVisible(visible);
                    }
                    clusterOverlay.updateClusters();
                }
            }
        });
    }

    @Override
    public List<Marker> getMarkers(String type) {
        return null;
    }

    @Override
    public void onDestory() {


        if (mHandlerThread != null) {
            mHandlerThread.quit();
        }
        if (mOverlayMap != null && mOverlayMap.size() > 0) {
            Set<String> strings = mOverlayMap.keySet();
            for (String key : strings) {
                mOverlayMap.get(key).onDestroy();
            }
            mOverlayMap = null;
        }
        mAMap = null;
    }

    @Override
    public void setaMap(AMap aMap) {
    }

    @Override
    public void setMarkerClickListener(OnCtmMarkerClickListener listener) {
        mMarkerClickListener = listener;
    }


    @Override
    public void setSameIdMarkersVisible(final String type, final String id, final boolean visible) {
        if (TextUtils.isEmpty(type) || TextUtils.isEmpty(id))
            return;

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                boolean isChange = false;
                ClusterOverlay clusterOverlay = mOverlayMap.get(type);
                if (clusterOverlay != null) {
                    List<ClusterItem> clusterItems = clusterOverlay.getClusterItems();
                    for (ClusterItem item : clusterItems) {
                        String beanId = null;
                        //根据不同类型，转换实体
                        if (Constants.MARKER_TYPE_TASK.equals(type)) {
                            MissionLocationEntity.BodyBean object = (MissionLocationEntity.BodyBean) item.getObject();
                            beanId = object.getTaskTypeId();
                        } else if (Constants.MARKER_TYPE_PEOPLE.equals(type)) {
                            StaffLocationInfoEntity object = (StaffLocationInfoEntity) item.getObject();
                            beanId = object.getRoleId();
                        }
                        //改变数据
                        if (id.equals(beanId)) {
                            item.setVisible(visible);
                            isChange = true;
                        }
                    }
                    if (isChange) {
                        //重新刷新marker
                        clusterOverlay.updateClusters();
                    }
                }
            }
        });
    }

    @Override
    public void putDrawables(Map drawables) {
        mDrawables.putAll(drawables);
    }

    @Override
    public boolean removeMarkers(List list, String type) {
        return false;
    }


    private void initThreadHandler() {
        mHandlerThread.start();
        mHandler = new DataHandle(mHandlerThread.getLooper());
    }


    private void initData(List<ClusterItem> list, String type) {
        boolean b = mDatas.containsKey(type);
        if (b) {
            List list1 = mDatas.get(type);
//            list1.clear();
            list1.add(list);
        } else {
            mDatas.put(type, list);
            //清除数据
        }
        //数据构造完成，发送通知，构建聚合marker
        Message message = new Message();
        message.obj = list;
        message.what = DataHandle.ADD_DATA;
        Bundle bundle = new Bundle();
        bundle.putString(S_STYPE, type);
        message.setData(bundle);
        mHandler.sendMessage(message);
    }

    private ClusterOverlay addToClusterOverlay(List<ClusterItem> itemList, String type) {

        ClusterOverlay clusterOverlay = null;
        clusterOverlay = getClusterOverlay(type);
        if (clusterOverlay != null) {

            clusterOverlay.addClusterItems(itemList);
        }
        return clusterOverlay;
    }

    private ClusterOverlay getClusterOverlay(String type) {
        boolean b1 = mOverlayMap.containsKey(type);
        ClusterOverlay clusterOverlay;
        if (b1) {
            //类型已存在，单独添加
            clusterOverlay = mOverlayMap.get(type);
        } else {
            clusterOverlay = initClusterOverlay(type);
        }
        return clusterOverlay;
    }

    @NonNull
    private ClusterOverlay initClusterOverlay(String type) {
        ClusterOverlay clusterOverlay;
        int size = SizeUtils.dp2px(clusterRadius);
        clusterOverlay = new ClusterOverlay(mAMap, size, Factory.app());
        mOverlayMap.put(type, clusterOverlay);
        clusterOverlay.setClusterRenderer(this);
        clusterOverlay.setAddMarkerListener(this);
        clusterOverlay.setOnClusterClickListener(new ClusterClickListener() {
            @Override
            public boolean onClick(Marker marker) {
                Object object = marker.getObject();
                if (object == null) {
                    return false;
                }
                if (object instanceof Cluster) {
                    //聚合点事件
                    Cluster clus = (Cluster) object;
                    List<ClusterItem> clusterItems = clus.getClusterItems();
                    LatLngBounds.Builder builder = new LatLngBounds.Builder();
                    for (ClusterItem clusterItem : clusterItems) {
                        builder.include(clusterItem.getPosition());
                    }
                    LatLngBounds latLngBounds = builder.build();
                    mAMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, SizeUtils.dp2px(30)));
                    if (mMarkerClickListener != null)
                        return mMarkerClickListener.onClusterClick(marker);
                } else if (mMarkerClickListener != null) {
                    //非聚合点的点击事件
                    return mMarkerClickListener.onNoClusterClick(marker, marker.getObject());
                }

                return false;
            }
        });
        return clusterOverlay;
    }


    @Override
    public Drawable getDrawAble(int clusterNum, String type, Object data) {
        //返回不同类型的marker的icon
        Drawable drawable = null;
        if (clusterNum == 1) {
            if (data instanceof StaffLocationInfoEntity) {
                String personRoleId = ((StaffLocationInfoEntity) data).getRoleId();

                drawable = mDrawables.get(personRoleId);
            } else if (data instanceof MissionLocationEntity.BodyBean) {
                String id = ((MissionLocationEntity.BodyBean) data).getTaskTypeName();
                if(TextUtils.isEmpty(id)){
                    String taskTypeId = ((MissionLocationEntity.BodyBean) data).getTaskTypeId();
                    drawable = mDrawables.get(taskTypeId);
                }else {
                    drawable = mDrawables.get(id);
                }
            } else if (drawable == null) {
                drawable = mDrawables.get(type);
            }
        } else if (Constants.MARKER_TYPE_PEOPLE.equals(type)) {
            return drawable;

        } else if (Constants.MARKER_TYPE_WARN_FACILITY_FIRM.equals(type)) {
            drawable = mClusterDra1;
        }else {
            drawable = mClusterDra;
        }
        return drawable;
    }

    /**
     * 聚合点的icon
     */
    private Bitmap drawCircle(int radius, int color) {

        Bitmap bitmap = Bitmap.createBitmap(radius * 2, radius * 2,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        RectF rectF = new RectF(0, 0, radius * 2, radius * 2);
        paint.setColor(color);
        canvas.drawArc(rectF, 0, 360, true, paint);
        return bitmap;
    }

    @Override
    public void onAddMarkerLisener(Marker marker) {
        if (mAddMarkerListener != null) {
            mAddMarkerListener.onAddMarkerLisener(marker);
        }
    }

    @Override
    public void setAddMarkerListener(onAddMarkerListener addMarkerListener) {
        mAddMarkerListener = addMarkerListener;
    }

    @Override
    public void onCameraChange(CameraPosition cameraPosition) {

    }

    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
            Set<String> strings = mOverlayMap.keySet();
            for (String str : strings) {
                ClusterOverlay clusterOverlay = mOverlayMap.get(str);
                clusterOverlay.updateClusters();
            }
            EventBus.getDefault().post(new EventEntity(EventBusConstants.MAP_OCAMERA_CHANGE_FINISH, Constants.SUCCEED));
    }

    /**
     * 操作线程
     */
    class DataHandle extends Handler {
        static final int ADD_DATA = 0;
        static final int SET_MAP_BOUND = 1;
        static final int REFRESH_DATA = 2;

        public DataHandle(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
                case ADD_DATA:
                    List data = (List) msg.obj;
                    String string = msg.getData().getString(S_STYPE);
                    addToClusterOverlay(data, string);
                    break;
                case SET_MAP_BOUND:
                    break;
                case REFRESH_DATA:
                    List data1 = (List) msg.obj;
                    String str = msg.getData().getString(S_STYPE);
                    refreshClusterOver(data1, str);

                    break;
            }
        }
    }

    private void refreshClusterOver(List<ClusterItem> data, String type) {
        ClusterOverlay clusterOverlay = getClusterOverlay(type);
        if (clusterOverlay != null) {
            List<ClusterItem> clusterItems = clusterOverlay.getClusterItems();
            clusterItems.clear();
            clusterItems.addAll(data);
            clusterOverlay.updateClusters();
        }
    }
}
